package org.yu.team2023.flashdays.blockentity;


import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.FormattedCharSequence;
import net.minecraft.world.entity.player.Inventory;
import net.minecraftforge.client.gui.widget.ExtendedButton;
import org.jetbrains.annotations.NotNull;
import org.yu.team2023.flashdays.FlashDays;
import org.yu.team2023.flashdays.registries.EasyScreen;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class TreasureUpgradeScreen extends EasyScreen<TreasureUpgradeMenu> {
    public static final ResourceLocation BACKGROUND = new ResourceLocation(FlashDays.MODID, "textures/gui/treasure__upgrade.png");
    private final Component TIP_UPGRADEABLE = Component.translatable("tip.flashdays.upgradeable");
    private final Component TIP_NOT_UPGRADEABLE = Component.translatable("tip.flashdays.not_upgradeable");

    public TreasureUpgradeScreen(TreasureUpgradeMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
        super(pMenu, pPlayerInventory, pTitle);
        this.inventoryLabelY = 73;
        this.inventoryLabelX = 10;
    }

    @Override
    protected void init() {
        super.init();
        addRenderableWidget(new LearnButton(leftPos + 111, topPos + 53, 63, 14, new Supplier<Component>() {
            @Override
            public Component get() {
                if (menu.getBlockEntity().canUpgrade())
                    return TIP_UPGRADEABLE;
                return TIP_NOT_UPGRADEABLE;
            }
        }, button -> {
            if (menu.getBlockEntity().canUpgrade()) {
                menu.getBlockEntity().sendUpgradeRequest();
            }
        }));
        addRenderableWidget(new VecScTextView(190+leftPos, 2+topPos, 67, 111, () -> {
           var list= menu.getBlockEntity().getAttributeTooltipsWithLevel();
            var res = new ArrayList<Component>();
            res.add(menu.getBlockEntity().getUpgradeProgress());
            res.addAll(list);
            if(!menu.getBlockEntity().outputEmpty())
                res.add(Component.translatable("tips.flashdays.treasure_output_not_empty"));
           return res;
        })).setTextScale(.8F);
    }

    @Override
    protected int getImageWidth() {
        return 260;
    }

    @Override
    protected int getImageHeight() {
        return 166;
    }

    @Override
    public void renderAfter(@NotNull GuiGraphics pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {

    }

    @Override
    protected void renderBg(GuiGraphics guiGraphics, float pPartialTick, int pMouseX, int pMouseY) {
        guiGraphics.blit(BACKGROUND, leftPos, topPos, 0, 0, getImageWidth(), getImageHeight(), getImageWidth(), getImageHeight());

    }
    private static class LearnButton extends ExtendedButton {
        private final Supplier<Component> msgGetter;

        public LearnButton(int xPos, int yPos, int width, int height, Supplier<Component> msgGetter, Button.OnPress handler) {
            super(xPos, yPos, width, height, Component.literal("learn"), handler);
            this.msgGetter = msgGetter;
        }

        @Override
        public @NotNull Component getMessage() {
            return msgGetter.get();
        }
    }
    private static class VecScTextView extends TextView {

        protected float scrollY;



        public VecScTextView(int x, int y, int w, int h, Supplier<List<? extends Component>> list) {
            super(x, y, w, h,list);
        }


        @Override
        public void render(@NotNull GuiGraphics pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
            pPoseStack.enableScissor(getX(),getY(),getX()+width,getY()+height);
            renderWidget(pPoseStack, pMouseX, pMouseY, pPartialTick);
            pPoseStack.disableScissor();
        }

        @Override
        protected float getStartY() {
            return getY()-scrollY;
        }

        public float getContentHeight(){
            return Math.max(getTextHeight(), height);
        }

        private float getMaxScroll()
        {
            return this.getContentHeight() -this.height ;
        }

        private void applyScrollLimits()
        {
            float max = getMaxScroll();

            if (max < 0)
            {
                max /= 2;
            }

            if (this.scrollY < 0.0F)
            {
                this.scrollY = 0.0F;
            }

            if (this.scrollY > max)
            {
                this.scrollY = max;
            }
        }
        @Override
        public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) {
            if(isMouseOver(pMouseX,pMouseY)){
                scrollY = (int) (scrollY-pDelta*getScrollAmount());
                applyScrollLimits();
                return true;
            }
            return false;
        }
        protected int getScrollAmount()
        {
            return 20;
        }
    }
    private static class TextView extends AbstractWidget {
        private final Supplier<List<? extends Component>> textGetter;

        @Setter
        protected int color;
        private final Font font;
        @Getter
        protected float textScale =1f;
        public TextView(int pX, int pY, int pWidth, int pHeight, Supplier<List<? extends Component>> textGetter) {
            super(pX, pY, pWidth, pHeight, Component.literal("textview"));
            this.textGetter=textGetter;
            this.font= Minecraft.getInstance().font;
        }
        protected float getTextHeight(){
            return textGetter.get().stream().map(component -> (font.wordWrapHeight(component,getRealWidth())*textScale)).reduce(0f,Float::sum);
        }
        protected int getRealWidth(){
            return (int) (width/ textScale);
        }

        public void setTextScale(float scale) {
            this.textScale = Math.max(scale,0.1f);
        }
        protected float getStartY(){
            return getY()-getTextHeight()/2+getHeight()/2;
        }
        @Override
        public void renderWidget(@NotNull GuiGraphics pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
            List<? extends Component> text=textGetter.get();
            var w=getRealWidth();
            float nextY=getStartY();

            for (Component component : text) {
                for(FormattedCharSequence formattedcharsequence : font.split(component, w)) {
                    pPoseStack.pose().pushPose();
                    pPoseStack.pose().translate(getX(),nextY,0);
                    pPoseStack.pose().scale(textScale, textScale, textScale);
                    pPoseStack.drawString(font, formattedcharsequence, 0, 0, color, false);
                    nextY += 9*textScale;
                    pPoseStack.pose().popPose();
                }

            }

        }


        @Override
        protected void updateWidgetNarration(@NotNull NarrationElementOutput p_259858_) {

        }
    }
}
